﻿using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using HiSport.Application.Service.Order.OrderSiteService.Service;
using HiSport.Application.Service.Transaction.Pay.Dtos;
using HiSport.Application.Service.Transaction.TransactionConfig.Service;
using HiSport.Core.Entity.Pay;
using HiSport.Core;
using HiSport.Core.Util;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel;
using HiSport.Core.Entity.Order;
using Newtonsoft.Json;
using Microsoft.AspNetCore.Rewrite;
using Essensoft.Paylink.WeChatPay.V2.Request;

namespace HiSport.Application.Service.Transaction.Pay.Service
{

    [ApiDescriptionSettings("payManagement", Tag = "payment", SplitCamelCase = false)]
    public class PayService : ITransient, IPayService, IDynamicApiController
    {

        private readonly IPayNotifyService _payNotifyService;
        private readonly Essensoft.Paylink.WeChatPay.V2.IWeChatPayClient _clientV2;
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly ITransactionConfigService _transactionConfigService;
        private readonly IOrderSiteService _orderSiteService;
        private readonly SqlSugarRepository<PayRecord> _payRecord;
        private readonly SqlSugarRepository<OrderSite> _orderSite;
        private readonly SqlSugarRepository<OrderSiteInfo> _orderSiteInfo;
        private readonly SqlSugarRepository<PayTripartiteRecord> _payTripartiteRecord;
        private readonly IHttpClientFactory _httpClientFactory;
        public PayService(IHttpContextAccessor httpContextAccessor,
            ITransactionConfigService transactionConfigService,
            SqlSugarRepository<PayRecord> payRecord,
            Essensoft.Paylink.WeChatPay.V2.IWeChatPayClient clientV2,
            IHttpClientFactory httpClientFactory,
            IPayNotifyService payNotifyService,
            SqlSugarRepository<PayTripartiteRecord> payTripartiteRecord,
            SqlSugarRepository<OrderSite> orderSite,
              SqlSugarRepository<OrderSiteInfo> orderSiteInfo,
            IOrderSiteService orderSiteService)
        {
            _httpContextAccessor = httpContextAccessor;
            _transactionConfigService = transactionConfigService;
            _orderSiteService = orderSiteService;
            _payRecord = payRecord;
            _payNotifyService = payNotifyService;
            _httpClientFactory = httpClientFactory;
            _clientV2 = clientV2;
            _payTripartiteRecord = payTripartiteRecord;
            _orderSite = orderSite;
            _orderSiteInfo = orderSiteInfo;
        }


        /// <summary>
        /// 付款码支付
        /// </summary>
        /// <returns></returns>
        [ApiDescriptionSettings(Name = "MicroPay"), HttpPost]
        [DisplayName("付款码支付")]
        public async Task<PayOutDto> MicroPay(PayInputDto inputDto)
        {
            var result = new PayOutDto();

            //已支付金额
            decimal alreadyPai = 0;

            //获取支付配置
            var paySetting = await _transactionConfigService.GetDefaultPaySetting();

            #region  支付检查
            var order = await _orderSite.AsQueryable().FirstAsync(x => x.OrderNum == inputDto.OrderNum);
            if (order == null)
            {
                throw Oops.Oh("查询不到订单");
            }

            if (order.OrderPayState == OrderPayStateEnum.AllPayment)
            {
                throw Oops.Oh("订单已全部支付");
            }

            if (order.OrderState == OrderStateEnum.Complete)
            {
                throw Oops.Oh("订单已完成");
            }

            if (inputDto.ActualPayAmount > order.PayableAmount)
            {
                throw Oops.Oh("支付金额大于订单金额");
            }

            if (order.ActualPayAmount + inputDto.ActualPayAmount > order.PayableAmount)
            {
                throw Oops.Oh("支付金额超过订单金额");
            }
            result.OrderPayState = order.OrderPayState;

            #endregion


            //创建支付单 
            var payRecord = await AddPayRecord(new PayRecordCreateDto()
            {
                OrderId = order.Id,
                OrderNo = order.OrderNum,
                PayAmount = inputDto.ActualPayAmount,
                PayType = inputDto.PayType,
            });
            result.PayNo = payRecord.PayNo;

            switch (inputDto.PayType)
            {
                case PayTypeEnum.WeChat:

                    #region 微信支付
                    //微信下单订单
                    var payMicroPayRequest = new WeChatPayMicroPayRequest()
                    {
                        Body = "订场订单",
                        OutTradeNo = payRecord.PayNo,
                        TotalFee = Convert.ToInt32(payRecord.PayAmount * 100),
                        SpBillCreateIp = "42.193.49.185",
                        AuthCode = inputDto.AuthCode,
                    };

                    //支付
                    var response = await _clientV2.ExecuteAsync(payMicroPayRequest, paySetting.WeChatPay);

                    if (response.ReturnCode == Essensoft.Paylink.WeChatPay.V2.WeChatPayCode.Success)
                    {
                        if (response.ResultCode == Essensoft.Paylink.WeChatPay.V2.WeChatPayCode.Success)
                        {
                            result.PayState = PayStateEnum.Success;
                            result.Msg = "支付成功";

                            //回填 TransactionId
                            payRecord.TransactionId = response.TransactionId;
                            var payRecordRes = await _payRecord.UpdateAsync(payRecord);
                            if (payRecordRes)
                            {
                                if (order.ActualPayAmount + inputDto.ActualPayAmount == order.PayableAmount)
                                {
                                    order.OrderState = OrderStateEnum.Complete;
                                    order.OrderPayState = OrderPayStateEnum.AllPayment;
                                    result.OrderPayState = OrderPayStateEnum.AllPayment;

                                    //查询子订单
                                    var orderinfo1 = _orderSiteInfo.AsQueryable().Where(x => x.OrderSiteId == order.Id).ToList();

                                    //修改子订单状态
                                    foreach (var item in orderinfo1)
                                    {
                                        if (item.ScheduledSiteState == ScheduledSiteStateEnum.OfflineUnpaid)
                                        {
                                            item.ScheduledSiteState = ScheduledSiteStateEnum.OfflinePaid;
                                        }
                                    }
                                    await _orderSiteInfo.UpdateRangeAsync(orderinfo1);

                                }
                                else
                                {
                                    order.OrderPayState = OrderPayStateEnum.PartialPay;
                                    result.OrderPayState = OrderPayStateEnum.PartialPay;
                                }
                                //支付金额加上现在支付金额
                                order.ActualPayAmount += inputDto.ActualPayAmount;
                                var orderRes = await _orderSite.UpdateAsync(order);
                                if (!orderRes)
                                {
                                    result.PayState = PayStateEnum.Wait;
                                    result.Msg = "支付成功订单回调失败";
                                }
                            }
                            else
                            {
                                result.PayState = PayStateEnum.Wait;
                                result.Msg = "支付成功TransactionId 回填失败";
                            }
                        }
                        else
                        {
                            if (response.ErrCode.ToUpper() == "SYSTEMERROR"
                                || response.ErrCode.ToUpper() == "USERPAYING"
                                || response.ErrCode.ToUpper() == "BANKERROR")
                            {
                                result.PayState = PayStateEnum.Wait;
                                result.Msg = "待查询确定订单";
                            }
                            else
                            {
                                result.PayState = PayStateEnum.Fail;
                                result.Msg = response.ErrCodeDes;
                            }
                        }
                    }
                    else
                    {
                        result.PayState = PayStateEnum.Fail;
                        result.Msg = response.ReturnMsg;
                    }

                    //添加三方交易记录
                    await AddPayTripartiteRecord(new PayTripartiteRecordCreateDto()
                    {
                        OrderId = order.Id,
                        PayRecordId = payRecord.Id,
                        Request = $"{JsonConvert.SerializeObject(payRecord)}_{JsonConvert.SerializeObject(paySetting.WeChatPay)}",
                        Result = $"{JsonConvert.SerializeObject(response)}_{JsonConvert.SerializeObject(result)}"
                    });
                    #endregion
                    break;
                case PayTypeEnum.Cash:

                    //查询子订单
                    var orderinfo = _orderSiteInfo.AsQueryable().Where(x => x.OrderSiteId == order.Id).ToList();

                    //修改子订单状态
                    foreach (var item in orderinfo)
                    {
                        if (item.ScheduledSiteState == ScheduledSiteStateEnum.OfflineUnpaid)
                        {
                            item.ScheduledSiteState = ScheduledSiteStateEnum.OfflinePaid;
                        }
                    }

                    //修改主订单状态
                    order.OrderState = OrderStateEnum.Complete;
                    order.OrderPayState = OrderPayStateEnum.AllPayment;
                    result.Msg = "支付成功";
                    result.PayState = PayStateEnum.Success;
                    result.OrderPayState = OrderPayStateEnum.AllPayment;

                    if (!(await _orderSite.UpdateAsync(order)))
                    {
                        result.PayState = PayStateEnum.Fail;
                        result.Msg = "支付失败";
                    }
                    else
                    {
                        await _orderSiteInfo.UpdateRangeAsync(orderinfo);
                    }
                    break;
                default:
                    break;
            }

            return result;

        }

        /// <summary>
        /// 订场支付
        /// </summary>
        /// <returns></returns>
        [ApiDescriptionSettings(Name = "OrderSitePay"), HttpPost]
        [DisplayName("订场支付")]
        public async Task<PayOutDto> OrderSitePay(PayInputDto inputDto)
        {
            var result = new PayOutDto();

            //已支付金额
            decimal alreadyPai = 0;

            //获取支付配置
            var paySetting = await _transactionConfigService.GetDefaultPaySetting();

            var order = await _orderSite.AsQueryable().FirstAsync(x => x.OrderNum == inputDto.OrderNum);
            if (order == null)
            {
                throw Oops.Oh("查询不到订单");
            }

            if (order.OrderPayState == OrderPayStateEnum.AllPayment)
            {
                throw Oops.Oh("订单已全部支付");
            }

            if (order.OrderState == OrderStateEnum.Complete)
            {
                throw Oops.Oh("订单已完成");
            }

            if (inputDto.ActualPayAmount > order.PayableAmount)
            {
                throw Oops.Oh("支付金额大于订单金额");
            }

            if (order.ActualPayAmount + inputDto.ActualPayAmount > order.PayableAmount)
            {
                throw Oops.Oh("支付金额超过订单金额");
            }
            result.OrderPayState = order.OrderPayState;

            //创建支付单 
            var payRecord = await AddPayRecord(new PayRecordCreateDto()
            {
                OrderId = order.Id,
                OrderNo = order.OrderNum,
                PayAmount = inputDto.ActualPayAmount,
                PayType = inputDto.PayType,
            });
            result.PayNo = payRecord.PayNo;

            switch (inputDto.PayType)
            {
                case PayTypeEnum.WeChat:

                    #region 微信支付
                    //微信下单订单
                    var payMicroPayRequest = new WeChatPayMicroPayRequest()
                    {
                        Body = "订场订单",
                        OutTradeNo = payRecord.PayNo,
                        TotalFee = Convert.ToInt32(payRecord.PayAmount * 100),
                        SpBillCreateIp = "42.193.49.185",
                        AuthCode = inputDto.AuthCode,
                    };

                    //支付
                    var response = await _clientV2.ExecuteAsync(payMicroPayRequest, paySetting.WeChatPay);

                    if (response.ReturnCode == Essensoft.Paylink.WeChatPay.V2.WeChatPayCode.Success)
                    {
                        if (response.ResultCode == Essensoft.Paylink.WeChatPay.V2.WeChatPayCode.Success)
                        {
                            result.PayState = PayStateEnum.Success;
                            result.Msg = "支付成功";

                            //回填 TransactionId
                            payRecord.TransactionId = response.TransactionId;
                            payRecord.PayState = PayRecordStateEnum.AllPayment;
                            var payRecordRes1 = await _payRecord.UpdateAsync(payRecord);
                            if (payRecordRes1)
                            {
                                if (order.ActualPayAmount + inputDto.ActualPayAmount == order.PayableAmount)
                                {
                                    order.OrderState = OrderStateEnum.Complete;
                                    order.OrderPayState = OrderPayStateEnum.AllPayment;
                                    result.OrderPayState = OrderPayStateEnum.AllPayment;
                                }
                                else
                                {
                                    order.OrderPayState = OrderPayStateEnum.PartialPay;
                                    result.OrderPayState = OrderPayStateEnum.PartialPay;
                                }
                                //支付金额加上现在支付金额
                                order.ActualPayAmount += inputDto.ActualPayAmount;
                                var orderRes1 = await _orderSite.UpdateAsync(order);
                                if (!orderRes1)
                                {
                                    result.PayState = PayStateEnum.Wait;
                                    result.Msg = "支付成功订单回调失败";
                                }
                            }
                            else
                            {
                                result.PayState = PayStateEnum.Wait;
                                result.Msg = "支付成功TransactionId 回填失败";
                            }
                        }
                        else
                        {
                            if (response.ErrCode.ToUpper() == "SYSTEMERROR"
                                || response.ErrCode.ToUpper() == "USERPAYING"
                                || response.ErrCode.ToUpper() == "BANKERROR")
                            {
                                result.PayState = PayStateEnum.Wait;
                                result.Msg = "待查询确定订单";
                            }
                            else
                            {
                                result.PayState = PayStateEnum.Fail;
                                result.Msg = response.ErrCodeDes;
                            }
                        }
                    }
                    else
                    {
                        result.PayState = PayStateEnum.Fail;
                        result.Msg = response.ReturnMsg;
                    }

                    //添加三方交易记录
                    await AddPayTripartiteRecord(new PayTripartiteRecordCreateDto()
                    {
                        OrderId = order.Id,
                        PayRecordId = payRecord.Id,
                        Request = $"{JsonConvert.SerializeObject(payRecord)}_{JsonConvert.SerializeObject(paySetting.WeChatPay)}",
                        Result = $"{JsonConvert.SerializeObject(response)}_{JsonConvert.SerializeObject(result)}"
                    });
                    #endregion
                    break;
                case PayTypeEnum.Cash:
                    result.PayState = PayStateEnum.Success;
                    result.Msg = "支付成功";

                    //回填 TransactionId
                    payRecord.TransactionId = "4";
                    payRecord.PayState = PayRecordStateEnum.AllPayment;
                    var payRecordRes = await _payRecord.UpdateAsync(payRecord);
                    if (payRecordRes)
                    {
                        if (order.ActualPayAmount + inputDto.ActualPayAmount == order.PayableAmount)
                        {
                            order.OrderState = OrderStateEnum.Complete;
                            order.OrderPayState = OrderPayStateEnum.AllPayment;
                            result.OrderPayState = OrderPayStateEnum.AllPayment;
                            //查询子订单
                            var orderinfo1 = _orderSiteInfo.AsQueryable().Where(x => x.OrderSiteId == order.Id).ToList();

                            //修改子订单状态
                            foreach (var item in orderinfo1)
                            {
                                if (item.ScheduledSiteState == ScheduledSiteStateEnum.OfflineUnpaid)
                                {
                                    item.ScheduledSiteState = ScheduledSiteStateEnum.OfflinePaid;
                                }
                            }
                            await _orderSiteInfo.UpdateRangeAsync(orderinfo1);
                        }
                        else
                        {
                            order.OrderPayState = OrderPayStateEnum.PartialPay;
                            result.OrderPayState = OrderPayStateEnum.PartialPay;
                        }
                        //支付金额加上现在支付金额
                        order.ActualPayAmount += inputDto.ActualPayAmount;
                        var orderRes2 = await _orderSite.UpdateAsync(order);
                        if (!orderRes2)
                        {
                            result.PayState = PayStateEnum.Wait;
                            result.Msg = "支付成功订单回调失败";
                        }
                    }
                    else
                    {
                        result.PayState = PayStateEnum.Wait;
                        result.Msg = "支付成功TransactionId 回填失败";
                    }
                    break;
                default:
                    throw Oops.Oh($"支付方式未开通");
                    break;
            }

            return result;

        }

        /// <summary>
        /// 查询支付订单
        /// </summary>
        /// <param name="payNo"></param>
        /// <returns></returns>
        [ApiDescriptionSettings(Name = "PayOrderQuery"), HttpPost]
        [DisplayName("查询微信支付订单")]
        public async Task<PayOutDto> PayOrderQuery(string payNo)
        {
            var result = new PayOutDto()
            {
                PayNo = payNo
            };

            //获取支付配置
            var paySetting = await _transactionConfigService.GetDefaultPaySetting();


            //根据订单编号查询 支付单号
            var payRecord = await _payRecord.AsQueryable().OrderByDescending(x => x.CreateTime).FirstAsync(x => x.PayNo == payNo);
            if (payRecord == null)
            {
                throw Oops.Oh("支付信息不存在");
            }

            var order = await _orderSite.AsQueryable().FirstAsync(x => x.OrderNum == payRecord.OrderNo);
            if (order == null)
            {
                throw Oops.Oh("查询不到订单");
            }
            if (order.OrderPayState == OrderPayStateEnum.AllPayment)
            {
                result.Msg = "支付成功";
                return result;
            }
            if (order.ActualPayAmount + payRecord.PayAmount > order.PayableAmount)
            {
                throw Oops.Oh("支付金额超过订单金额");
            }

            result.OrderPayState = order.OrderPayState;


            var request = new WeChatPayOrderQueryRequest
            {
                OutTradeNo = payRecord.PayNo
            };
            var response = await _clientV2.ExecuteAsync(request, paySetting.WeChatPay);


            if (response.ReturnCode == Essensoft.Paylink.WeChatPay.V2.WeChatPayCode.Success)
            {
                if (response.ResultCode == Essensoft.Paylink.WeChatPay.V2.WeChatPayCode.Success)
                {
                    if (response.TradeState == Essensoft.Paylink.WeChatPay.V2.WeChatPayCode.Success)
                    {
                        result.PayState = PayStateEnum.Success;
                        result.Msg = "支付成功";

                        //回填 TransactionId
                        payRecord.TransactionId = response.TransactionId;
                        payRecord.PayState = PayRecordStateEnum.AllPayment;
                        var payRecordRes = await _payRecord.UpdateAsync(payRecord);

                        if (payRecordRes)
                        {
                            if (order.ActualPayAmount + payRecord.PayAmount == order.PayableAmount)
                            {
                                order.OrderState = OrderStateEnum.Complete;
                                order.OrderPayState = OrderPayStateEnum.AllPayment;
                                result.OrderPayState = OrderPayStateEnum.AllPayment;
                                await UpdateOrderSiteInfoState(order.Id);
                            }
                            else
                            {
                                order.OrderState = OrderStateEnum.Afoot;
                                order.OrderPayState = OrderPayStateEnum.PartialPay;
                                result.OrderPayState = OrderPayStateEnum.PartialPay;
                            }
                            //支付金额加上现在支付金额
                            order.ActualPayAmount += payRecord.PayAmount;
                            var orderRes = await _orderSite.UpdateAsync(order);
                            if (!orderRes)
                            {
                                result.PayState = PayStateEnum.Wait;
                                result.Msg = "支付成功订单回调失败";
                            }
                        }
                        else
                        {
                            result.PayState = PayStateEnum.Wait;
                            result.Msg = "支付成功TransactionId 回填失败";
                        }
                    }
                    else
                    {
                        result.PayState = PayStateEnum.Fail;
                        result.Msg = response.TradeStateDesc;
                    }


                }
                else
                {
                    if (response.ErrCode.ToUpper() == "SYSTEMERROR")
                    {
                        result.PayState = PayStateEnum.Wait;
                        result.Msg = "待查询确定订单";
                    }
                    else
                    {
                        result.PayState = PayStateEnum.Success;
                        result.Msg = response.ErrCodeDes;
                    }
                }
            }
            else
            {
                result.PayState = PayStateEnum.Fail;
                result.Msg = response.ReturnMsg;
            }

            return result;
        }

        /// <summary>
        /// 修改子订单状态
        /// </summary>
        /// <returns></returns>
        private async Task<bool> UpdateOrderSiteInfoState(long orderSiteId)
        {

            var orderSiteInfos = await _orderSiteInfo.AsQueryable().Where(x => x.OrderSiteId == orderSiteId).ToListAsync();

            foreach (var item in orderSiteInfos)
            {
                if (item.ScheduledSiteState == ScheduledSiteStateEnum.OfflineUnpaid)
                {
                    item.ScheduledSiteState = ScheduledSiteStateEnum.OfflinePaid;
                }
                else if (item.ScheduledSiteState == ScheduledSiteStateEnum.OnlineUnpaid)
                {
                    item.ScheduledSiteState = ScheduledSiteStateEnum.OnlinePaid;
                }
                else if (item.ScheduledSiteState == ScheduledSiteStateEnum.FixedUnpaid)
                {
                    item.ScheduledSiteState = ScheduledSiteStateEnum.FixedPaid;
                }

            }

            return await _orderSiteInfo.UpdateRangeAsync(orderSiteInfos);
        }

        /// <summary>
        /// 添加支付记录
        /// </summary>
        /// <returns></returns>
        private async Task<PayRecord> AddPayRecord(PayRecordCreateDto inputDto)
        {
            var res = await _payRecord.InsertReturnEntityAsync(new PayRecord()
            {
                OrderId = inputDto.OrderId,
                OrderNo = inputDto.OrderNo,
                PayAmount = inputDto.PayAmount,
                PayNo = FunctionUtil.GetOrderNum(OrderNumType.PAY),
                PayType = inputDto.PayType,
                PayState = PayRecordStateEnum.Unpaid,
            });
            return res;
        }

        /// <summary>
        /// 添加第三方支付记录
        /// </summary>
        /// <param name="inputDto"></param>
        /// <returns></returns>
        private async Task<bool> AddPayTripartiteRecord(PayTripartiteRecordCreateDto inputDto)
        {
            var res = await _payTripartiteRecord.InsertAsync(new PayTripartiteRecord()
            {
                OrderId = inputDto.OrderId,
                PayRecordId = inputDto.PayRecordId,
                Request = inputDto.Request,
                Result = inputDto.Result,
            });

            return res;
        }

        private void WeChatPay()
        {

        }
    }
}
